package org.dftproject.familysearch.core;

import static java.lang.System.out;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.dftproject.genesis.data.genealogy.GenealogyConstants;
import org.dftproject.genesis.data.genealogy.IPerson;
import org.dftproject.genesis.data.genealogy.Sex;
import org.dftproject.genesis.data.genealogy.impl.EventImpl;
import org.dftproject.genesis.data.genealogy.impl.PersonImpl;
import org.dftproject.genesis.data.genealogy.impl.RoleImpl;
import org.dftproject.genesis.data.impl.AttributeImpl;
import org.familysearch.api.familytree.v1.Fact;
import org.familysearch.api.familytree.v1.FamilyTree;
import org.familysearch.api.familytree.v1.GenderType;
import org.familysearch.api.familytree.v1.Person;

public class DFTAdapter {

	public IPerson adapt(FamilyTree tree) {

		return null;
	}

	public IPerson adapt(Person person, List<Fact> relations, Map<String, Person> idMap) {
		List<Person> children = new LinkedList<Person>();
		List<Person> parents = new LinkedList<Person>();
		List<Person> spouses = new LinkedList<Person>();
		for (Fact r : relations) {
			switch (r.getScope()) {
			case PARENT_CHILD:
				if (r.getChild() != null) {
					Person p = idMap.get(r.getChild());
					if (p != null)
						children.add(p);
				} else {
					assert r.getParent() != null;
					Person p = idMap.get(r.getParent());
					if (p != null)
						parents.add(p);
				}
				break;
			case COUPLE:
				assert r.getSpouse() != null;
				Person p = idMap.get(r.getSpouse());
				if (p != null)
					spouses.add(p);
				break;
			case PERSON:
				break;
			}
			out.printf("Fact of scope %s%n", r.getScope().name());
		}
		GenderType gender = person.getInformation().getGender();
		PersonImpl dftPerson = new PersonImpl();
		// dftPerson.addAttribute(new AttributeImpl(GenealogyConstants.name, new
		// FullName(getName(person))));
		dftPerson.addAttribute(new AttributeImpl(GenealogyConstants.sex, getSex(gender)));
		// dftPerson.addRole()
		List<PersonImpl> dftParents = adaptParents(parents, dftPerson);
		return null;
	}

	public static List<PersonImpl> adaptParents(List<Person> parents, PersonImpl dftPerson) {
		List<PersonImpl> results = new LinkedList<PersonImpl>();
		EventImpl birthEvent = new EventImpl();
		RoleImpl childBirthRole = new RoleImpl(GenealogyConstants.Child, dftPerson, birthEvent);
		birthEvent.addRole(childBirthRole);
		dftPerson.addRole(childBirthRole);
		for (Person p : parents) {
			PersonImpl dftParent = new PersonImpl();
			RoleImpl parentBirthRole = new RoleImpl(getParentConstant(p), dftParent, birthEvent);
			dftParent.addRole(parentBirthRole);
			birthEvent.addRole(parentBirthRole);
			results.add(dftParent);
		}
		return results;

	}

	public static Sex getSex(GenderType gender) {
		switch (gender) {
		case MALE:
			return Sex.Male;
		case FEMALE:
			return Sex.Female;
		case UNKNOWN:
			return null;
		default:
			throw new RuntimeException("unknown gender");
		}
	}

	public static String getParentConstant(Person p) {
		switch (p.getInformation().getGender()) {
		case MALE:
			return GenealogyConstants.Father;
		case FEMALE:
			return GenealogyConstants.Mother;
		case UNKNOWN:
		default:
			return GenealogyConstants.Parent;
		}
	}

}
